import { RequestStateCode, themePackStoreBaseUrl } from "@/common/constant";
import useMounted from "@/hooks/useMounted";
import Themepack from "@/shared/themepack/renderer";
import axios from "axios";
import { useEffect, useState } from "react";

let themeStoreConfig: IThemeStoreItem[];

interface IThemeStoreItem {
    publishName: string;
    hash: string;
    packageName: string;
    config: ICommon.IThemePack;
    id?: string;
}

function raceWithData<T>(promises: Array<Promise<T>>): Promise<T> {
    const promiseCount = promises.length;
    return new Promise((resolve, reject) => {
        let isResolved = false;
        let rejectedNum = 0;
        promises.forEach((promise) => {
            promise
                .then((data) => {
                    if (!isResolved) {
                        isResolved = true;
                        resolve(data);
                    }
                })
                .catch((e) => {
                    ++rejectedNum;
                    if (rejectedNum === promiseCount) {
                        reject(e);
                    }
                });
        });
    });
}

export default function () {
    const [themes, setThemes] = useState(themeStoreConfig || []);
    const [loadingState, setLoadingState] = useState(
        RequestStateCode.PENDING_FIRST_PAGE,
    );
    const isMounted = useMounted();

    useEffect(() => {
        if (themeStoreConfig) {
            setThemes(themeStoreConfig);
            setLoadingState(RequestStateCode.FINISHED);
        } else {
            raceWithData(
                themePackStoreBaseUrl.map(
                    async (it, index) =>
                        [await axios.get(it + ".publish/publish.json").then(res => {
                            if (typeof res.data !== "object") {
                                throw new Error("Invalid data");
                            }
                            return res;
                        }), index] as const,
                ),
            )
                .then(([res, index]) => {
                    const data: IThemeStoreItem[] = res.data;
                    const pickedUrl = themePackStoreBaseUrl[index];

                    data.forEach((theme) => {
                        theme.config.srcUrl = `${pickedUrl}.publish/${theme.publishName}.mftheme`;
                        if (theme.config.preview) {
                            theme.config.preview = Themepack.replaceAlias(
                                theme.config.preview,
                                pickedUrl + theme.packageName + "/",
                                false,
                            );
                        }
                        if (theme.config.thumb) {
                            theme.config.thumb = Themepack.replaceAlias(
                                theme.config.thumb,
                                pickedUrl + theme.packageName + "/",
                                false,
                            );
                        }
                    });
                    themeStoreConfig = data;

                    if (isMounted.current) {
                        setLoadingState(RequestStateCode.FINISHED);
                        setThemes(data);
                    }
                })
                .catch((e) => {
                    setLoadingState(RequestStateCode.ERROR);
                });
        }
    }, []);

    return [themes, loadingState] as const;
}
